

//funcion para crear el objeto webGL que se encargara (mediante THREE) de las configuraciones de WebGL

var actualizarInfo = true;//TODO


	function controller_webgl(){
		
		
		this.getDomContainerPanelController = function(){return domContainerPanelController;};
		
		//+++++++++ VARS (importantes) ++++++++++
		var _this = this;//referencia al propio objeto
		
		var domContainerPanelController; //maneja los paneles que flotan sobre el domContainer
		
		var escenaAlemWrapper = null; //se crea a partir de una escena particular (new AlemScene(), que crea la escena, las luces, el mundo)
		
		var activeWrapperScene = null;//la idea es tener distintas escenas, y usar esta var para apuntar a la escena activa
		
		var renderer = null; 
			
		var contextViewport = null;
		
		var domContainer = null, stats;
		
		var SCREEN_WIDTH, SCREEN_HEIGHT;	
	
		var renderizarContexto = CONSTANTS.START_RENDERING_CONTEXT; 
		//+++++++++ fin VARS (importantes) ++++++++++
		
		
		//+++++++++ PARA DEBUG ++++++++++
		var dataRenderer = null;//DEBUG. panel con informacion de renderizado
		this.getDragDebugCube = function(){return activeWrapperScene.getDragDebugCube();}//DEBUG.
		//+++++++++ fin PARA DEBUG ++++++++++
		
		
		
		//+++++++++ SPRITE ACTUAL ++++++++++
		var sprt; //el sprite actual
		this.getActiveSprite = function(){return sprt;};
		this.setActiveSprite = function(sp){sprt = sp;};
		//+++++++++ fin SPRITE ACTUAL ++++++++++	
		
		
		
		//+++++++++ MARCADORES PARA INICIO/FIN DE ANIMACION ++++++++++
		this.getMarcadorInicio = function(){return activeWrapperScene.getMarcadorInicio();};
		this.getMarcadorFinal = function(){return activeWrapperScene.getMarcadorFinal();};
		//+++++++++ fin MARCADORES PARA INICIO/FIN DE ANIMACION ++++++++++	
		
		
//		this.shadows = function(shadowsOn){
//			if(shadowsOn){light.castShadow = true;
//				var scn = activeWrapperScene.getScene();
//				renderer.shadowMapEnabled = true;
//				renderer.shadowMapSoft = true;
//				if (scn){
//					
//				}
//			}else{light.castShadow = false;
//				var scn = activeWrapperScene.getScene();
//				renderer.shadowMapEnabled = false;
//				renderer.shadowMapSoft = false;
//				if (scn){
//					
//				}
//			}
//		}
		
		//+++++++++ API ++++++++++	
//		this.setSceneWrapper = function(wrapper){
//			activeWrapperScene = wrapper;
//			_this.todo();
//		}
		var _sceneBuilder = new SceneBuilder(_this);
		this.activeWrapper = function(){return activeWrapperScene;};
		
		//TODO (lo llama el controller jerarquia para cambiar la opacidad de los niveles)
		this.getSceneWrapper = function(){
			if (activeWrapperScene instanceof FirstPersonScene || activeWrapperScene instanceof AlemScene){
				return activeWrapperScene;
			}
			
			return null;
		}
		
		this.updateSceneWrapper = function(){
			
			if (activeWrapperScene instanceof FirstPersonScene || activeWrapperScene instanceof AlemScene){
				CONTROLLER_JERARQUIA_SPACES.generateVisualRepresentations(activeWrapperScene);
				//activeWrapperScene.update()
			}
		};
		
		this.setSceneWrapper = function(wrapperName){
			
			var wrapper = null;
			 wrapper = _sceneBuilder.generateScene(wrapperName);
			 
			 CONTROLLER_CONTROL_FLOW.setDomPanels(wrapper.getPanelsConfiguration());
			if(wrapper == null) alert('wrapper null');
			
			if (activeWrapperScene && activeWrapperScene != wrapper) activeWrapperScene.deactivate();
			activeWrapperScene = wrapper;
			_this.updateSceneWrapper();
			wrapper.activate();
			
			
		};
		
		//renderizar, o no, de acuerdo al valor de la variable pasada como parametro
		var renderBool = false;
		this.toggleRenderizar = function(){
			return _this.renderizar(!renderBool)
		};
		
		
		this.renderizar = function(valor){
			if (renderBool == valor) return;
			
			renderBool = valor;
			if(renderBool){	
				animate();
				if (activeWrapperScene.context){
					if (activeWrapperScene.context.visible instanceof Function)
					activeWrapperScene.context.visible(renderizarContexto);
				}
			}
			return renderBool;
		};
	
		
		
		
		//(toggle) muestra u oculta la escena (obj) del frente de la universidad
		this.mostrarEscena = function(valor){
			
			console.log('TODO --> mostrar escena');//TODO
			
//			if (escenaCompleta && valor == undefined){
//				escenaCompleta.visible = !escenaCompleta.visible;
//				escenaPlanos.visible = !escenaPlanos.visible;
//			}else if (escenaCompleta && valor != undefined){
//				escenaCompleta.visible = valor;
//				escenaPlanos.visible = !valor;
//			}
		};	
		
		this.addToScene = function(object){activeWrapperScene.addToScene(object);};
		this.getRenderer = function(){return renderer;};
		this.getCamera = function(){return activeWrapperScene.getCamera();}; 
		this.getScene = function(){return activeWrapperScene.getScene();};
		this.getCameraControls = function(){return activeWrapperScene.getCameraControls();};
		this.getDomContainer = function(){return domContainer; };
		this.getContextViewport = function(){return contextViewport; };
		this.getStatsDomElement = function(){return stats.getDomElement();};
		
		this.getRenderizarContexto = function(){return renderizarContexto;};
		this.toggleRenderizarContexto = function(){ 
			renderizarContexto = !renderizarContexto;
			if (activeWrapperScene.context){activeWrapperScene.context.visible(renderizarContexto);}
		};
		//+++++++++ fin API ++++++++++
		
		
		//+++++++++ PATCHES ++++++++++
		this.moverContextoEscena = function(altura){
			activeWrapperScene.moverContextoEscena(altura);
		}
		//+++++++++ fin PATCHES ++++++++++
		
		
			
		
			
//---------------------------------------------------------------------------------------------------------------------
//--------------------------------------------- INIT ------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
		this.init = function() {
			
			//+++++++++ ELEMENTO CANVAS PARA WEBGL ++++++++++
			domContainer = document.getElementById( 'canvas_webgl' );
			//+++++++++ fin ELEMENTO CANVAS PARA WEBGL ++++++++++

			
			//+++++++++ TAMAÑO DEL CONTAINER ++++++++++
			SCREEN_WIDTH = domContainer.offsetWidth;
			SCREEN_HEIGHT = domContainer.offsetHeight;
			//+++++++++ fin TAMAÑO DEL CONTAINER ++++++++++
			
			
			//+++++++++ RENDERER WEBGL ++++++++++
			renderer = new THREE.WebGLRenderer( {preserveDrawingBuffer   : true /*required to support .toDataURL()*/, antialias: true } );
			renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
			renderer.domElement.style.position = "relative";	
			renderer.setScissor( 0,0,SCREEN_WIDTH, SCREEN_HEIGHT );
			renderer.setViewport( 0,0,SCREEN_WIDTH, SCREEN_HEIGHT );
			renderer.sortObjects = false;
			
			//renderer.setFaceCulling (false);
			domContainer.appendChild( renderer.domElement );
			
			if (SOMBRA){
				renderer.shadowMapEnabled = true;
				renderer.shadowMapSoft = true;
			}
			renderer.shadowCameraNear = 3;
			//renderer.shadowCameraFar = camera.far;
			renderer.shadowCameraFov = 50;

			renderer.shadowMapBias = 0.0039;
			renderer.shadowMapDarkness = 0.5;

			renderer.shadowMapWidth = 1024;
			renderer.shadowMapHeight = 1024;
			//+++++++++ fin RENDERER WEBGL ++++++++++
			
			
			//+++++++++ ESCENA (default) ++++++++++	
			//activeWrapperScene = 
				_this.setSceneWrapper(); //default scene wrapper
			//+++++++++ fin ESCENA (default) ++++++++++
			
			
			//+++++++++ STATS ++++++++++
			stats = new Stats();
			//+++++++++ fin STATS ++++++++++
			
			
			//+++++++++ PANELES SOBRE EL DOM ++++++++++
			domContainerPanelController = new DomContainerPanel(_this);
			dataRenderer = domContainerPanelController.getPanelDataRenderer();
			domContainerPanelController.generateCameraPanel();
			//+++++++++ fin PANELES SOBRE EL DOM ++++++++++
			
			renderBool=true;
			animate();
		};
		
		
		
//---------------------------------------------------------------------------------------------------------------------
//--------------------------------------------- ANIMATE ------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------		
		//OJO!!! lo que se haga aca adentro va a afectar terriblemente el rendimiento!!!
		function animate() {

			if (renderBool) {
			
				//updates
				if ( CONSTANTS.STATS_ENABLED ) stats.update();
				TWEEN.update();					
				//fin updates
				
				if(activeWrapperScene) activeWrapperScene.animate();//se renderiza de acuerdo a la escena (wrapper) que se este mostrando
				
				//actulizamos estadisticas de WebGL (programas, calls, texturas, etc)
				if (dataRenderer.isVisible() && actualizarInfo ){
					updatePanelRendererData();
				}
				
				requestAnimationFrame( animate );
				
			}//fin if renderizar bool
		};
		
		
		
		//-------------------------------------------------------------------------------
		//---------------------- DATA RENDER INFORMATION GATHERING ----------------------
		//-------------------------------------------------------------------------------
		function updatePanelRendererData(){
			var innerHTML = "<h3>Memory</h3>"
				+ "<lu><li>Programs:"+ renderer.info.memory.programs+" </li></lu>"
				+ "<lu><li>Geometries:"+ renderer.info.memory.geometries+" </li></lu>"
				+ "<lu><li>Textures:"+ renderer.info.memory.textures+" </li>"
				+ "<lu><li>Material Count:"+ THREE.MaterialCount+" </li>"
				+ "<lu><li>Geometry Count:"+ THREE.GeometryCount+" </li>"
				+ "<lu><li>Object3D Count:"+ THREE.Object3DCount+" </li></lu>"
				+ "<h3>Render</h3>"
				+ "<lu><li>Calls:"+ renderer.info.render.calls+" </li></lu>"
				+ "<lu><li>Vertices:"+ renderer.info.render.vertices+" </li></lu>"
				+ "<lu><li>Faces:"+ renderer.info.render.faces+" </li></lu>";
			
			dataRenderer.data(innerHTML);
			
//			if (activeWrapperScene.renderizarContexto())
//			{
//				innerHTML =  "<h3>Render Contexto</h3>"
//					+ "<lu><li>Calls:"+ renderer.info.render.calls+" </li></lu>"
//					+ "<lu><li>Vertices:"+ renderer.info.render.vertices+" </li></lu>"
//					+ "<lu><li>Faces:"+ renderer.info.render.faces+" </li></lu>";
//					dataRenderer.append(innerHTML);
//			}
			
			actualizarInfo = false;
			
			
		};
		
		
}/*fin objeto webgl*/